// import CryptoJS from "crypto-js";
// import { SM4 } from 'gm-crypto';
// import { sm4 } from 'sm-crypto'
const sm4 = require('sm-crypto').sm4

// 必须与服务端约定一致
const strKey = "WwNSkh8Th8SxXVsz";
const secretKey = getHexStr(stringToUtf8Bytes(strKey));

export function decrypt(data, iv) {
  const ivHex = getHexStr(stringToUtf8Bytes(iv))
  let decrypted = sm4.decrypt(base64ToUint8Array(data), secretKey, {mode: 'cbc', iv: ivHex}) // 解密，cbc 模式
  return decrypted;
}

function getHexStr (byteArray) {
  return Array.from(byteArray, byte => 
    byte.toString(16).padStart(2, '0')
  ).join('')
}

function base64ToUint8Array(base64Str) {
  return new Uint8Array(wx.base64ToArrayBuffer(base64Str));
}

function stringToUtf8Bytes(str) {
  const bytes = [];
  
  for (let i = 0; i < str.length; i++) {
    let charCode = str.charCodeAt(i);
    
    // 处理单字节字符 (0x0000 - 0x007F)
    if (charCode < 0x80) {
      bytes.push(charCode);
    }
    // 处理双字节字符 (0x0080 - 0x07FF)
    else if (charCode < 0x800) {
      bytes.push(0xC0 | (charCode >> 6));
      bytes.push(0x80 | (charCode & 0x3F));
    }
    // 处理三字节字符 (0x0800 - 0xFFFF)，排除代理对
    else if (charCode < 0xD800 || charCode >= 0xE000) {
      bytes.push(0xE0 | (charCode >> 12));
      bytes.push(0x80 | ((charCode >> 6) & 0x3F));
      bytes.push(0x80 | (charCode & 0x3F));
    }
    // 处理四字节字符 (代理对 0xD800 - 0xDFFF)
    else {
      // 确保有下一个字符
      if (i + 1 < str.length) {
        const nextCharCode = str.charCodeAt(i + 1);
        // 验证是否是有效的代理对
        if (nextCharCode >= 0xDC00 && nextCharCode < 0xE000) {
          // 计算完整的 Unicode 码点
          const codePoint = ((charCode - 0xD800) << 10) + (nextCharCode - 0xDC00) + 0x10000;
          
          bytes.push(0xF0 | ((codePoint >> 18) & 0x07));
          bytes.push(0x80 | ((codePoint >> 12) & 0x3F));
          bytes.push(0x80 | ((codePoint >> 6) & 0x3F));
          bytes.push(0x80 | (codePoint & 0x3F));
          
          i++; // 跳过已处理的代理对
          continue;
        }
      }
      // 无效的代理对，使用替换字符 U+FFFD
      bytes.push(0xEF, 0xBF, 0xBD);
    }
  }
  
  return new Uint8Array(bytes);
}